Release 10.1A: OpenEdge Development:
ProDataSets


Sample procedures: using attributes and methods

This section extends the example procedures from Chapter 4 "Dynamic ProDataSet Basics" to make them more truly dynamic. It then shows small sections of code to illustrate the use of each of the methods and attributes.

To modify the example, create a copy of DynamicDataSet.p and name the new procedure DynamicDataSet2.p. Modify the parameter list to eliminate the pcBuffers parameter and to reorder the others to base the ProDataSet definition on the database tables it is filled from. For example:

/* DynamicDataSet2.p -- creates a dynamic DataSet and Data-Sources, 
    fills it for a key value passed in, and returns it. */ 
DEFINE INPUT  PARAMETER pcSources    AS CHARACTER  NO-UNDO. 
DEFINE INPUT  PARAMETER pcSourceKeys AS CHARACTER  NO-UNDO. 
DEFINE INPUT  PARAMETER pcFields     AS CHARACTER  NO-UNDO. 
DEFINE INPUT  PARAMETER pcKeyValue   AS CHARACTER  NO-UNDO. 
DEFINE OUTPUT PARAMETER DATASET-HANDLE phDataSet. 

Also, you need another handle variable to point to a series of dynamic temp-tables you will create for the database sources, as shown:

DEFINE VARIABLE hTable AS HANDLE NO-UNDO. 

Modify the block of code that walks through the buffer handle list in DynamicDataSet.p to walk through the list of database source tables and create a dynamic temp-table LIKE each in turn.

Prepare each temp-table definition and then add the table’s default buffer handle to the ProDataSet. The following block of code replaces the code beginning with DO iEntry = 1 TO NUM-ENTRIES(pcBuffers):

DO iEntry = 1 TO NUM-ENTRIES(pcSources): 
    CREATE TEMP-TABLE hTable. 
    hTable:CREATE-LIKE(ENTRY(iEntry, pcSources)). 
    hTable:TEMP-TABLE-PREPARE("tt" + ENTRY(iEntry, pcSources)). 
    phDataSet:ADD-BUFFER(hTable:DEFAULT-BUFFER-HANDLE). 
END. 

As with other parts of these procedures, you can use the same temp-table handle variable for each of the temp-tables because once it has been added to the ProDataSet, the ProDataSet structure keeps track of the handle’s value and position within the ProDataSet. You are then free to reuse the same handle variable to create another new dynamic temp-table that will have its own value for that handle.

There is one more small change. The pcKeyValue parameter used to retrieve data related to a single top-level table is changed to accept an expression such as “= 1” or “< 10”, by removing the equal sign literal (“ = “) from the QUERY-PREPARE method. This lets you have one or more top-level records in the ProDataSet. This will help illustrate some of the object attributes as we go along, as shown:

hQuery:QUERY-PREPARE("FOR EACH " + ENTRY(1, pcSources) + 
                                 " WHERE " + ENTRY(1, pcSourceKeys) + 
                                 pcKeyValue). 

The rest of the procedure remains the same. Now the dependency on static temp-table definitions has been removed, and there is no need to pass any handles in the parameter list that would not survive being passed across the AppServer boundary.

Copy DynamicMain.p to a new variant called DynamicMain2.p. In this new procedure, you can delete the static temp-table definitions because you are making everything dynamic. This is why dynamicDataSet2.p now creates them as dynamic temp-tables instead of receiving their handles.

You’ll need several variables along the way to hold various attributes and other values, so define them at the top of the procedure, as shown:

DEFINE VARIABLE hBuffer   AS HANDLE     NO-UNDO. 
DEFINE VARIABLE iBuffer   AS INTEGER    NO-UNDO. 
DEFINE VARIABLE hQuery    AS HANDLE     NO-UNDO. 
DEFINE VARIABLE hRelation AS HANDLE     NO-UNDO. 

Change the RUN statement to run DynamicDataSet2.p, and rearrange the parameters to match. Change the pcKeyValues parameter “1” to be “= 1”, as shown:

RUN DynamicDataSet2.p (INPUT "Customer,Order,SalesRep", 
                      INPUT "CustNum,OrderNum,SalesRep", 
                      INPUT "CustNum,CustNum", 
                      INPUT "= 1", 
                      OUTPUT DATASET-HANDLE hDataSet). 

Create a dynamic query that you will use in several parts of the procedure:

CREATE QUERY hQuery. 

Remove all the rest of the code (the DISPLAY blocks) except for the final DELETE OBJECT statement.

At this point, you can add a series of blocks of code following the CREATE QUERY statement to illustrate how to access the ProDataSet dynamically.

This first example is a block of code that retrieves the number of buffers in the ProDataSet. For each one, it retrieves its buffer handle and then does a dynamic FIND-FIRST method on that handle to position to the first record in that temp-table. (FIND-FIRST is, of course, a standard Progress dynamic buffer method.) The MESSAGE statement shows the first two fields in each buffer:

/* This block shows how to access the DataSet's buffers 
   and the data in their temp-table records. */ 
DO iBuffer = 1 TO hDataSet:NUM-BUFFERS: 
    hBuffer = hDataSet:GET-BUFFER-HANDLE(iBuffer). 
    hBuffer:FIND-FIRST(). 
    MESSAGE "Buffer " hBuffer:NAME SKIP 
            hBuffer:BUFFER-FIELD(1):NAME 
            hBuffer:BUFFER-FIELD(1):BUFFER-VALUE SKIP 
            hBuffer:BUFFER-FIELD(2):NAME 
            hBuffer:BUFFER-FIELD(2):BUFFER-VALUE 
        VIEW-AS ALERT-BOX. 
END. 

When you run this, you can confirm that the dynamic temp-tables have the same data as the static temp-tables did before:

        

A ProDataSet buffer that is not the child of a relation is referred to as a top-level buffer. There might be more than one top-level buffer in a ProDataSet. The NUM-TOP-BUFFERS attribute gives you the number of those buffers, as shown in the following snytax:

Syntax
[ integer-var = ] dataset-handle:NUM-TOP-BUFFERS 

The GET-TOP-BUFFER method returns the handle of one of those buffers using its index within the list of top-level buffers. For example:

Syntax
[ handle-var = ] dataset-handle:GET-TOP-BUFFER( buffer-index ) 

This example code for DynamicMain2.p shows that ttCustomer and ttSalesRep are both top-level buffers, because they do not participate in a relation:

/* This block shows the attribute and method that access the 
   list of DataSet buffers that are not children in a relation.*/ 
DO iBuffer = 1 TO hDataSet:NUM-TOP-BUFFERS: 
    hBuffer = hDataSet:GET-TOP-BUFFER(iBuffer). 
    MESSAGE "Buffer " iBuffer hBuffer:NAME 
        VIEW-AS ALERT-BOX. 
END. 

The code output proves the point:

   


Copyright © 2005 Progress Software Corporation
www.progress.com
Voice: (781) 280-4000
Fax: (781) 280-4095